import { Injectable, UnauthorizedException, Logger } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { UserService } from '../../user/services/user.service';
import { UserLogService } from '../../user-log/services/user-log.service';
import { User } from '../../user/entities/user.entity';
import { AuthResponseDto } from '../dto/auth-response.dto';
import { JwtPayload } from '../strategies/jwt.strategy';

@Injectable()
export class AuthService {
  private readonly logger = new Logger(AuthService.name);

  constructor(
    private readonly userService: UserService,
    private readonly userLogService: UserLogService,
    private readonly jwtService: JwtService,
    private readonly configService: ConfigService,
  ) {}

  /**
   * 用户登录
   * @param user 用户对象
   * @param ipAddress IP地址
   * @param userAgent 用户代理
   * @returns 认证响应数据
   */
  async login(user: User, ipAddress?: string, userAgent?: string): Promise<AuthResponseDto> {
    try {
      const payload: JwtPayload = { 
        sub: user.id, 
        username: user.username 
      };

      // 生成访问令牌
      const accessToken = this.jwtService.sign(payload, {
        expiresIn: this.configService.get('jwt.expiresIn'),
      });

      // 生成刷新令牌
      const refreshToken = this.jwtService.sign(payload, {
        expiresIn: this.configService.get('jwt.refreshExpiresIn'),
      });

      // 用户行为日志现在由 UserLogInterceptor 统一处理
      // 移除手动日志记录，避免重复

      return new AuthResponseDto({
        accessToken,
        refreshToken,
        expiresIn: this.configService.get('jwt.expiresIn'),
        refreshExpiresIn: this.configService.get('jwt.refreshExpiresIn'),
      });
    } catch (error) {
      this.logger.error('用户登录失败', error.stack);
      throw error;
    }
  }

  /**
   * 验证用户凭据
   * @param username 用户名
   * @param password 密码
   * @returns 用户对象或null
   */
  async validateUser(username: string, password: string): Promise<User | null> {
    const user = await this.userService.findByUsername(username);
    if (user && await user.validatePassword(password)) {
      return user;
    }
    return null;
  }
} 